/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _DAL_QOS_POLICIES_
#define _DAL_QOS_POLICIES_

#include "base_type.h"
#include "locator.h"
#include "dal/string_sequence.h"

#ifdef __cplusplus
extern "C" {
#endif

#define DAL_LENGTH_UNLIMITED (-1)
static const long DAL_INFINITE_SECONDS = 0x7fffffff;
static const unsigned long DAL_INFINITE_NANOSECONDS = 0xffffffff;

enum dal_qos_policy_e
{
    DAL_INVALID_QOS_POLICY_ID = 0,  //< Does not refer to any valid QosPolicy

    // Standard QosPolicies
    DAL_USERDATA_QOS_POLICY_ID = 1,              //< UserDataQosPolicy
    DAL_DURABILITY_QOS_POLICY_ID = 2,            //< DurabilityQosPolicy
    DAL_PRESENTATION_QOS_POLICY_ID = 3,          //< PresentationQosPolicy
    DAL_DEADLINE_QOS_POLICY_ID = 4,              //< DeadlineQosPolicy
    DAL_LATENCYBUDGET_QOS_POLICY_ID = 5,         //< LatencyBudgetQosPolicy
    DAL_OWNERSHIP_QOS_POLICY_ID = 6,             //< OwnershipQosPolicy
    DAL_OWNERSHIPSTRENGTH_QOS_POLICY_ID = 7,     //< OwnershipStrengthQosPolicy
    DAL_LIVELINESS_QOS_POLICY_ID = 8,            //< LivelinessQosPolicy
    DAL_TIMEBASEDFILTER_QOS_POLICY_ID = 9,       //< TimeBasedFilterQosPolicy
    DAL_PARTITION_QOS_POLICY_ID = 10,            //< PartitionQosPolicy
    DAL_RELIABILITY_QOS_POLICY_ID = 11,          //< ReliabilityQosPolicy
    DAL_DESTINATIONORDER_QOS_POLICY_ID = 12,     //< DestinationOrderQosPolicy
    DAL_HISTORY_QOS_POLICY_ID = 13,              //< HistoryQosPolicy
    DAL_RESOURCELIMITS_QOS_POLICY_ID = 14,       //< ResourceLimitsQosPolicy
    DAL_ENTITYFACTORY_QOS_POLICY_ID = 15,        //< EntityFactoryQosPolicy
    DAL_WRITERDATALIFECYCLE_QOS_POLICY_ID = 16,  //< WriterDataLifecycleQosPolicy
    DAL_READERDATALIFECYCLE_QOS_POLICY_ID = 17,  //< ReaderDataLifecycleQosPolicy
    DAL_TOPICDATA_QOS_POLICY_ID = 18,            //< TopicDataQosPolicy
    DAL_GROUPDATA_QOS_POLICY_ID = 19,            //< GroupDataQosPolicy
    DAL_TRANSPORTPRIORITY_QOS_POLICY_ID = 20,    //< TransportPriorityQosPolicy
    DAL_LIFESPAN_QOS_POLICY_ID = 21,             //< LifespanQosPolicy
    DAL_DURABILITYSERVICE_QOS_POLICY_ID = 22,    //< DurabilityServiceQosPolicy
};

typedef struct dal_user_data_qos_policy_t
{
    SEQUENCE(octet) value;
} dal_user_data_qos_policy_t;

typedef struct dal_topic_data_qos_policy_t
{
    SEQUENCE(octet) value;
} dal_topic_data_qos_policy_t;

typedef struct dal_group_data_qos_policy_t
{
    SEQUENCE(octet) value;
} dal_group_data_qos_policy_t;

typedef struct dal_transport_priority_qos_policy_t
{
    long value;
} dal_transport_priority_qos_policy_t;

typedef struct dal_lifespan_qos_policy_t
{
    dal_duration_t duration;
} dal_lifespan_qos_policy_t;

typedef enum dal_durability_qos_policy_kind_e
{
    DAL_VOLATILE_DURABILITY_QOS,
    DAL_TRANSIENT_LOCAL_DURABILITY_QOS,
    DAL_TRANSIENT_DURABILITY_QOS,
    DAL_PERSISTENT_DURABILITY_QOS
} dal_durability_qos_policy_kind_e;

typedef struct dal_durability_qos_policy_t
{
    dal_durability_qos_policy_kind_e kind;
} dal_durability_qos_policy_t;

typedef enum dal_presentation_qos_policy_access_scope_kind_e
{
    DAL_INSTANCE_PRESENTATION_QOS,
    DAL_TOPIC_PRESENTATION_QOS,
    DAL_GROUP_PRESENTATION_QOS
} dal_presentation_qos_policy_access_scope_kind_e;

typedef struct dal_presentation_qos_policy_t
{
    dal_presentation_qos_policy_access_scope_kind_e access_scope;
    BOOLEAN coherent_access;
    BOOLEAN ordered_access;
} dal_presentation_qos_policy_t;

typedef struct dal_deadline_qos_policy_t
{
    dal_duration_t period;
} dal_deadline_qos_policy_t;

typedef struct dal_latency_budget_qos_policy_t
{
    dal_duration_t duration;
} dal_latency_budget_qos_policy_t;

typedef enum dal_ownership_qos_policy_e
{
    DAL_SHARED_OWNERSHIP_QOS,
    DAL_EXCLUSIVE_OWNERSHIP_QOS
} dal_ownership_qos_policy_e;

typedef struct dal_ownership_qos_policy_t
{
    dal_ownership_qos_policy_e kind;
} dal_ownership_qos_policy_t;

typedef struct dal_ownership_strength_qos_policy_t
{
    long value;
} dal_ownership_strength_qos_policy_t;

typedef enum dal_liveliness_qos_policy_kind_e
{
    DAL_AUTOMATIC_LIVELINESS_QOS,
    DAL_MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
    DAL_MANUAL_BY_TOPIC_LIVELINESS_QOS
} dal_liveliness_qos_policy_kind_e;

typedef struct dal_liveliness_qos_policy_t
{
    dal_liveliness_qos_policy_kind_e kind;
    dal_duration_t lease_duration;
} dal_liveliness_qos_policy_t;

typedef struct dal_time_based_filter_qos_policy_t
{
    dal_duration_t minimum_separation;
} dal_time_based_filter_qos_policy_t;

typedef struct dal_partition_qos_policy_t
{
    dal_stringseq_t name;
} dal_partition_qos_policy_t;

typedef enum dal_reliability_qos_policy_kind_e
{
    DAL_BEST_EFFORT_RELIABILITY_QOS,
    DAL_RELIABLE_RELIABILITY_QOS
} dal_reliability_qos_policy_kind_e;

typedef struct dal_reliability_qos_policy_t
{
    dal_reliability_qos_policy_kind_e kind;
    dal_duration_t max_blocking_time;
} dal_reliability_qos_policy_t;

typedef enum dal_destination_order_qos_policy_kind_e
{
    DAL_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS,
    DAL_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS
} dal_destination_order_qos_policy_kind_e;

typedef struct dal_destination_order_qos_policy_t
{
    dal_destination_order_qos_policy_kind_e kind;
} dal_destination_order_qos_policy_t;

typedef enum dal_history_qos_policy_kind_e
{
    DAL_KEEP_LAST_HISTORY_QOS,
    DAL_KEEP_ALL_HISTORY_QOS
} dal_history_qos_policy_kind_e;

typedef struct dal_history_qos_policy_t
{
    dal_history_qos_policy_kind_e kind;
    long depth;
} dal_history_qos_policy_t;

typedef struct dal_resource_limits_qos_policy_t
{
    long max_samples;
    long max_instances;
    long max_samples_per_instance;
} dal_resource_limits_qos_policy_t;

typedef struct dal_entity_factory_qos_policy_t
{
    BOOLEAN autoenable_created_entities;
} dal_entity_factory_qos_policy_t;

typedef struct dal_writer_data_lifecycle_qos_policy_t
{
    BOOLEAN autodispose_unregistered_instances;
} dal_writer_data_lifecycle_qos_policy_t;

typedef struct dal_reader_data_lifecycle_qos_policy_t
{
    dal_duration_t autopurge_nowriter_samples_delay;
    dal_duration_t autopurge_disposed_samples_delay;
} dal_reader_data_lifecycle_qos_policy_t;

typedef struct dal_durability_service_qos_policy_t
{
    dal_duration_t service_cleanup_delay;
    dal_history_qos_policy_kind_e history_kind;
    long history_depth;
    long max_samples;
    long max_instances;
    long max_samples_per_instance;
} dal_durability_service_qos_policy_t;

typedef struct dal_domain_participant_factory_qos_t
{
    dal_entity_factory_qos_policy_t entity_factory;
} dal_domain_participant_factory_qos_t;

typedef struct dal_domain_participant_qos_t
{
    // DDS spec.
    dal_user_data_qos_policy_t user_data;
    dal_entity_factory_qos_policy_t entity_factory;
    // extra
    const char* participant_name;
    BOOLEAN localhost_only;
    SEQUENCE(dal_locator_t) multicast_locator_seq;
    SEQUENCE(dal_locator_t) unicast_locator_seq;
} dal_domain_participant_qos_t;

typedef struct dal_topic_qos_t
{
    dal_topic_data_qos_policy_t topic_data;
    dal_durability_qos_policy_t durability;
    dal_durability_service_qos_policy_t durability_service;
    dal_deadline_qos_policy_t deadline;
    dal_latency_budget_qos_policy_t latency_budget;
    dal_liveliness_qos_policy_t liveliness;
    dal_reliability_qos_policy_t reliability;
    dal_destination_order_qos_policy_t destination_order;
    dal_history_qos_policy_t history;
    dal_resource_limits_qos_policy_t resource_limits;
    dal_transport_priority_qos_policy_t transport_priority;
    dal_lifespan_qos_policy_t lifespan;
    dal_ownership_qos_policy_t ownership;
} dal_topic_qos_t;

typedef struct dal_datawriter_qos_t
{
    dal_durability_qos_policy_t durability;
    dal_durability_service_qos_policy_t durability_service;
    dal_deadline_qos_policy_t deadline;
    dal_latency_budget_qos_policy_t latency_budget;
    dal_liveliness_qos_policy_t liveliness;
    dal_reliability_qos_policy_t reliability;
    dal_destination_order_qos_policy_t destination_order;
    dal_history_qos_policy_t history;
    dal_resource_limits_qos_policy_t resource_limits;
    dal_transport_priority_qos_policy_t transport_priority;
    dal_lifespan_qos_policy_t lifespan;
    dal_user_data_qos_policy_t user_data;
    dal_ownership_qos_policy_t ownership;
    dal_ownership_strength_qos_policy_t ownership_strength;
    dal_writer_data_lifecycle_qos_policy_t writer_data_lifecycle;
} dal_datawriter_qos_t;

typedef struct dal_publisher_qos_t
{
    dal_presentation_qos_policy_t presentation;
    dal_partition_qos_policy_t partition;
    dal_group_data_qos_policy_t group_data;
    dal_entity_factory_qos_policy_t entity_factory;
} dal_publisher_qos_t;

typedef struct dal_datareader_qos_t
{
    dal_durability_qos_policy_t durability;
    dal_deadline_qos_policy_t deadline;
    dal_latency_budget_qos_policy_t latency_budget;
    dal_liveliness_qos_policy_t liveliness;
    dal_reliability_qos_policy_t reliability;
    dal_destination_order_qos_policy_t destination_order;
    dal_history_qos_policy_t history;
    dal_resource_limits_qos_policy_t resource_limits;
    dal_user_data_qos_policy_t user_data;
    dal_ownership_qos_policy_t ownership;
    dal_time_based_filter_qos_policy_t time_based_filter;
    dal_reader_data_lifecycle_qos_policy_t reader_data_lifecycle;
} dal_datareader_qos_t;

typedef struct dal_subscriber_qos_t
{
    dal_presentation_qos_policy_t presentation;
    dal_partition_qos_policy_t partition;
    dal_group_data_qos_policy_t group_data;
    dal_entity_factory_qos_policy_t entity_factory;
} dal_subscriber_qos_t;

dal_domain_participant_qos_t* dal_create_default_participant_qos();
void dal_delete_participant_qos(dal_domain_participant_qos_t* qos);

dal_topic_qos_t* dal_create_default_topic_qos();
void dal_delete_topic_qos(dal_topic_qos_t* qos);

dal_publisher_qos_t* dal_create_default_publisher_qos();
void dal_delete_publisher_qos(dal_publisher_qos_t* qos);

dal_subscriber_qos_t* dal_create_default_subscriber_qos();
void dal_delete_subscriber_qos(dal_subscriber_qos_t* qos);

dal_datawriter_qos_t* dal_create_default_datawriter_qos();
void dal_delete_datawriter_qos(dal_datawriter_qos_t* qos);

dal_datareader_qos_t* dal_create_default_datareader_qos();
void dal_delete_datareader_qos(dal_datareader_qos_t* qos);

#define DAL_PARTICIPANT_QOS_DEFAULT (dal_domain_participant_qos_t*)NULL
#define DAL_TOPIC_QOS_DEFAULT (dal_topic_qos_t*)NULL
#define DAL_PUBLISHER_QOS_DEFAULT (dal_publisher_qos_t*)NULL
#define DAL_SUBSCRIBER_QOS_DEFAULT (dal_subscriber_qos_t*)NULL
#define DAL_DATAWRITER_QOS_DEFAULT (dal_datawriter_qos_t*)NULL
#define DAL_DATAREADER_QOS_DEFAULT (dal_datareader_qos_t*)NULL

#ifdef __cplusplus
}
#endif

#endif  // _DAL_QOS_POLICIES_